2020-2021 Sunseeker Telemetry and Lighting System
saph_ex1_pulseGeneration.c
Go to the documentation of this file.
1 /* --COPYRIGHT--,BSD
2  * Copyright (c) 2017, Texas Instruments Incorporated
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * * Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  *
12  * * Redistributions in binary form must reproduce the above copyright
13  * notice, this list of conditions and the following disclaimer in the
14  * documentation and/or other materials provided with the distribution.
15  *
16  * * Neither the name of Texas Instruments Incorporated nor the names of
17  * its contributors may be used to endorse or promote products derived
18  * from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  * --/COPYRIGHT--*/
32 //******************************************************************************
33 // saph_ex1_pulseGeneration.c - Pulse generation using the SAPH PPG and PHY.
34 //
35 // Description: Configure the PPG and PHY in the SAPH module manually (register
36 // mode instead of ASQ controlled) to generate 10 high frequency pulses on the
37 // dedicated CH0_OUT pin, once per second.
38 //
39 // MSP430FR6047
40 // ---------------
41 // /|\| |
42 // | | |
43 // --|RST |
44 // | P1.0|---> LED
45 // | |-USSXTIN
46 // | |-USSXTOUT
47 // | CH0_OUT|---> 10 pulses 1/sec at 10MHz
48 //
49 // Wallace Tran
50 // Texas Instruments Inc.
51 // June 2017
52 // Built with IAR Embedded Workbench V6.50 & Code Composer Studio V7.1
53 //******************************************************************************
54 #include "driverlib.h"
55 
56 void main(void)
57 {
58  // Stop WDT
59  WDT_A_hold(WDT_A_BASE);
60 
61  // Configure P1.0 as output for LED
62  GPIO_setAsPeripheralModuleFunctionOutputPin(
63  GPIO_PORT_P1,
64  GPIO_PIN0,
65  GPIO_PRIMARY_MODULE_FUNCTION
66  );
67 
68  // Disable the GPIO power-on default high-impedance mode to activate
69  // previously configured port settings
70  PMM_unlockLPM5();
71 
72  /* ---Begin Clock System Setup--- */
73  // Set DCO to 8MHz
74  CS_setDCOFreq(CS_DCORSEL_0, CS_DCOFSEL_3);
75  // Set SMCLK = MCLK = DCO, ACLK = VLOCLK
76  CS_initClockSignal(CS_SMCLK, CS_DCOCLK_SELECT, CS_CLOCK_DIVIDER_8);
77  CS_initClockSignal(CS_MCLK, CS_DCOCLK_SELECT, CS_CLOCK_DIVIDER_8);
78  CS_initClockSignal(CS_ACLK, CS_VLOCLK_SELECT, CS_CLOCK_DIVIDER_1);
79  /* ---End Clock System Setup--- */
80 
81  /* ---Begin initialize the HSPLL and wait for it to lock--- */
82  // Configure USSXT Oscillator
83  HSPLL_xtalInitParam xtalParam = {0};
84  xtalParam.oscillatorType = HSPLL_XTAL_OSCTYPE_XTAL;
85  xtalParam.oscillatorEnable = HSPLL_XTAL_ENABLE;
86  xtalParam.xtlOutput = HSPLL_XTAL_OUTPUT_ENABLE;
87  HSPLL_xtalInit(HSPLL_BASE, &xtalParam);
88 
89  // Check if oscillator is stable
90  while(HSPLL_getOscillatorStatus(HSPLL_BASE) == HSPLL_OSCILLATOR_NOT_STABILIZED);
91 
92  // Set up timer to wait in LPM for crystal stabilization time = 4096 clocks for crystal resonator.
93  // For 8MHz XTAL, 4096 clocks = 512us. Using VLO = 9.4kHz, wait 5 timer clock cycles = 532us.
94  Timer_A_initUpModeParam timerParam = {0};
95  timerParam.timerPeriod = 5;
96  timerParam.captureCompareInterruptEnable_CCR0_CCIE =
97  TIMER_A_CCIE_CCR0_INTERRUPT_ENABLE;
98  // Timer sourced from ACLK (VLO)
99  timerParam.clockSource = TIMER_A_CLOCKSOURCE_ACLK;
100  // Clear timer
101  timerParam.timerClear = TIMER_A_DO_CLEAR;
102  timerParam.startTimer = true;
103  Timer_A_initUpMode(TA4_BASE, &timerParam);
104 
105  // Enter LPM3 w/interrupts enabled
106  __bis_SR_register(LPM3_bits | GIE);
107 
108  // For debugger
109  __no_operation();
110 
111  // Init PLL
112  // Use the PLL multiplier setting to get 80MHz output from our 8MHz input
113  // Equation: PLL output clock frequency x 2 = input clock frequency x (hspllParam.multiplier+1)
114  // Input clock frequency = 8MHz
115  // Desired PLL output clock frequency = 80MHz
116  // hspllParam.multipler = 19
117  HSPLL_initParam hspllParam = {0};
118  hspllParam.multiplier = PLLM_19_H;
119  hspllParam.frequency = HSPLL_GREATER_THAN_6MHZ;
120  HSPLL_init(HSPLL_BASE, &hspllParam);
121 
122  // Power up the UUPS to start the PLL
123  UUPS_turnOnPower(UUPS_BASE, UUPS_POWERUP_TRIGGER_SOURCE_USSPWRUP);
124 
125  // Wait for UUPS to power up
126  while(UUPS_getPowerModeStatus(UUPS_BASE) != UUPS_POWERMODE_READY);
127 
128  // Wait for PLL to lock
129  while(HSPLL_isLocked(HSPLL_BASE) == HSPLL_UNLOCKED);
130 
131  /* ---End initialize the HSPLL and wait for it to lock--- */
132 
133  /* ---Begin setting up the PPG settings--- */
134  // 10 excitation pulses, 0 stop pulses, output low when inactive, high polarity
135  SAPH_unlock(SAPH_BASE);
136  SAPH_configPPGCountParam saphCountConfig = {0};
137  saphCountConfig.pauseLevel = SAPH_PPG_PAUSE_LEVEL_LOW;
138  saphCountConfig.pausePolarity = SAPH_PPG_PAUSE_POLARITY_HIGH;
139  saphCountConfig.excitationPulseCount = 0x000A;
140  SAPH_configurePPGCount(SAPH_BASE, &saphCountConfig);
141  // Low phase = 4 HSPLL cycles = 50ns
142  SAPH_setPPGLowPeriod(SAPH_BASE, 4);
143  // High phase = 4 HSPLL cycles = 50ns
144  SAPH_setPPGHighPeriod(SAPH_BASE, 4);
145  // Set up the PHY to output PPG on dedicated CH0_OUT pin
146  SAPH_configPHYParam saphPHYConfig = {0};
147  // Output PPG
148  saphPHYConfig.outputFunction = SAPH_PHY_OUTPUT_PULSEGENERATOR_SINGLE_DRIVE;
149  SAPH_configurePHY(SAPH_BASE, &saphPHYConfig);
150  // Enable the PPG
151  // TA2.1 trigger, CH0 output, register mode
152  SAPH_configPPGParam saphConfig = {0};
153  saphConfig.triggerSource = SAPH_PPG_TRIGGER_SOURCE_TIMER;
154  saphConfig.channelSelect = SAPH_PPG_CHANNEL_0;
155  saphConfig.portSelect = SAPH_PPG_PORT_CHARGED_BY_PPG;
156  SAPH_configurePPG(SAPH_BASE, &saphConfig);
157  /* ---End setting up the PPG settings--- */
158 
159  /* ---Begin configure TA2.1 for 1/sec to trigger the pulse generation and toggle LED--- */
160  Timer_A_initUpModeParam timerParam2 = {0};
161  timerParam2.timerPeriod = 9400;
162  TA2CCR1 = 4700;
163  TA2CCTL1 = OUTMOD_7 | CCIE; // Enable output signal to trigger PPG, enable interrupt
164  // Timer sourced from ACLK (VLO)
165  timerParam2.clockSource = TIMER_A_CLOCKSOURCE_ACLK;
166  // Clear timer
167  timerParam2.timerClear = TIMER_A_DO_CLEAR;
168  timerParam2.startTimer = true;
169  Timer_A_initUpMode(TA2_BASE, &timerParam2);
170  /* ---End configure TA2.1 for 1/sec to trigger the pulse generation and toggle LED--- */
171 
172  while(1)
173  {
174  // Enter LPM0 w/interrupt
175  __bis_SR_register(LPM0_bits | GIE);
176  // For debugger
177  __no_operation();
178  }
179 }
180 
181 // Timer A2 interrupt service routine
182 #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
183 #pragma vector = TIMER2_A1_VECTOR
184 __interrupt void Timer2_A1_ISR(void)
185 #elif defined(__GNUC__)
186 void __attribute__ ((interrupt(TIMER2_A1_VECTOR))) Timer2_A1_ISR (void)
187 #else
188 #error Compiler not supported!
189 #endif
190 {
191  switch(__even_in_range(TA2IV, TAIV__TAIFG))
192  {
193  case TAIV__NONE: break; // No interrupt
194  case TAIV__TACCR1:
195  GPIO_toggleOutputOnPin(GPIO_PORT_P1, GPIO_PIN0); // Toggle LED to show new cycle
196  break;
197  case TAIV__TAIFG: break; // overflow
198  default: break;
199  }
200 }
201 
202 // Timer A4 interrupt service routine
203 #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
204 #pragma vector = TIMER4_A0_VECTOR
205 __interrupt void Timer4_A0_ISR(void)
206 #elif defined(__GNUC__)
207 void __attribute__ ((interrupt(TIMER4_A0_VECTOR))) Timer4_A0_ISR (void)
208 #else
209 #error Compiler not supported!
210 #endif
211 {
212  // Stop the timer and wake up from LPM
213  Timer_A_startCounter(TA4_BASE, TIMER_A_STOP_MODE);
214  __bic_SR_register_on_exit(LPM3_bits | GIE);
215  __no_operation();
216 }
__no_operation()
__bic_SR_register_on_exit(LPM3_bits|GIE)
void main(void)